<?php
namespace app\controller\productAnyShoot;

use app\BaseController;
use app\service\TopviewApiService;
use app\service\PointsService;
use think\App;
use think\facade\Config;
use think\facade\Db;

class Task extends BaseController
{
    protected $apiService;

    public function __construct(App $app)
    {
        $this->apiService = new TopviewApiService();
        parent::__construct($app);
    }

    /**
     * 提交替换商品图片任务
     */
    public function submitReplaceImageTask()
    {
        try {
            $params = input('post.');
            
            // 获取用户ID（假设从认证中间件获取）
            $userId = $this->request->user->uid ?? 1; // 临时使用1，实际应从认证中获取
            
            // 积分校验与扣减：万物迁移图片替换任务，扣除2积分
            $pointsService = new \app\service\PointsService();
            $needPoints = 2;
            $userPoints = $pointsService->getUserPoints($userId);
            if ($userPoints < $needPoints) {
                return json(['code' => 400, 'msg' => "积分不足，需要{$needPoints}积分，当前余额{$userPoints}积分", 'data' => null]);
            }

            // 可选参数验证
            $allowedParams = [
                'templateId', 'productImageFileId', 'productMaskFileId', 
                'templateImageFileId', 'templateMaskFileId'
            ];
            
            $filteredParams = [];
            foreach ($allowedParams as $param) {
                if (isset($params[$param]) && !empty($params[$param])) {
                    $filteredParams[$param] = $params[$param];
                }
            }

            $filteredParams['mode'] = 'advanced';
            $filteredParams['generatingCount'] = 1;
            
            // 调用API提交任务
            $result = $this->apiService->submitProductAnyShootReplaceImageTask($filteredParams);
            
            // 检查API调用是否成功，只有成功时才保存到数据库
            if (!isset($result['taskId']) || empty($result['taskId'])) {
                return json([
                    'code' => 500,
                    'msg' => 'API调用失败，未返回有效的taskId',
                    'data' => $result
                ]);
            }
            
            // 保存任务到数据库并扣除积分
            Db::startTrans();
            try {
                // 扣除积分
                $pointsService->consume($userId, $needPoints, '万物迁移图片替换任务', $result['taskId']);
                
                $taskDbId = Db::name('product_anyshoot_tasks')->insertGetId([
                    'user_id' => $userId,
                    'task_id' => $result['taskId'],
                    'template_id' => $params['templateId'] ?? 0,
                    'product_image_file_id' => $params['productImageFileId'],
                    'product_mask_file_id' => $params['productMaskFileId'] ?? null,
                    'template_image_file_id' => $params['templateImageFileId'] ?? null,
                    'template_mask_file_id' => $params['templateMaskFileId'] ?? null,
                    'mode' => 'advanced',
                    'generating_count' => 1,
                    'status' => 1, // 图片生成中
                    'points_consumed' => $needPoints,
                    'create_time' => date('Y-m-d H:i:s')
                ]);
                
                Db::commit();
                
                return json([
                    'code' => 200, 
                    'msg' => '任务提交成功', 
                    'data' => [
                        'taskId' => $result['taskId'],
                        'dbTaskId' => $taskDbId,
                        'status' => 1,
                        'statusText' => '图片生成中',
                        'message' => '任务已提交，正在生成图片',
                        'consumed_points' => $needPoints,
                        'remaining_points' => $userPoints - $needPoints
                    ]
                ]);
                
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
            
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => $e->getMessage(), 'data' => null]);
        }
    }

    /**
     * 查询替换商品图片任务
     */
    public function queryReplaceImageTask()
    {
        try {
            $taskId = input('taskId', '');
            
            if (empty($taskId)) {
                return json([
                    'code' => 400,
                    'msg' => '缺少必需参数: taskId',
                    'data' => null
                ]);
            }

            // 先从数据库查询任务信息
            $taskInfo = Db::name('product_anyshoot_tasks')
                ->where('task_id', $taskId)
                ->find();
                
            if (!$taskInfo) {
                return json([
                    'code' => 404,
                    'msg' => '任务不存在',
                    'data' => null
                ]);
            }
            
            // 如果任务还在处理中，调用API查询最新状态
            if ($taskInfo['status'] == 1) { // 图片生成中
                $apiResult = $this->apiService->queryProductAnyShootReplaceImageTask($taskId);
                
                // 更新数据库中的任务状态
                $updateData = ['update_time' => date('Y-m-d H:i:s')];
                
                if (isset($apiResult['status'])) {
                    switch ($apiResult['status']) {
                        case 'success':
                            $updateData['status'] = 3; // 图转视频中（等待用户触发）
                            $updateData['image_complete_time'] = date('Y-m-d H:i:s');
                            if (isset($apiResult['anyfitImages'])) {
                                $keys = [];
                                $urls = [];
                                
                                foreach ($apiResult['anyfitImages'] as $image) {
                                    if (isset($image['key'])) {
                                        $keys[] = $image['key'];
                                    }
                                    if (isset($image['url'])) {
                                        $urls[] = $image['url'];
                                    }
                                }
                                
                                $updateData['result_image_keys'] = json_encode($keys);
                                $updateData['result_image_urls'] = json_encode($urls);
                            }
                            break;
                        case 'failed':
                            $updateData['status'] = 2; // 图片生成失败
                            $updateData['error_msg'] = $apiResult['message'] ?? $apiResult['errorMsg'] ?? '图片生成失败';
                            break;
                        case 'processing':
                            // 保持图片生成中状态
                            break;
                    }
                }
                
                // 更新数据库
                Db::name('product_anyshoot_tasks')
                    ->where('task_id', $taskId)
                    ->update($updateData);
                    
                // 重新查询更新后的数据
                $taskInfo = Db::name('product_anyshoot_tasks')
                    ->where('task_id', $taskId)
                    ->find();
            }
            
            // 返回数据库中的任务信息
            $statusText = [
                0 => '待处理',
                1 => '图片生成中', 
                2 => '图片生成失败',
                3 => '等待图转视频',
                4 => '图转视频中',
                5 => '图转视频成功',
                6 => '图转视频失败'
            ];
            $responseData = [
                'taskId' => $taskInfo['task_id'],
                'status' => $taskInfo['status'],
                'statusText' => $statusText[$taskInfo['status']] ?? '未知',
                'templateId' => $taskInfo['template_id'],
                'productImageFileId' => $taskInfo['product_image_file_id'],
                'createTime' => $taskInfo['create_time'],
                'updateTime' => $taskInfo['update_time'],
                'imageCompleteTime' => $taskInfo['image_complete_time'],
                'videoCompleteTime' => $taskInfo['video_complete_time'],
                'pointsConsumed' => $taskInfo['points_consumed']
            ];
            
            // 如果图片生成完成，添加结果图片
            if ($taskInfo['status'] >= 3 && (!empty($taskInfo['result_image_keys']) || !empty($taskInfo['result_image_urls']))) {
                $keys = !empty($taskInfo['result_image_keys']) ? json_decode($taskInfo['result_image_keys'], true) : [];
                $urls = !empty($taskInfo['result_image_urls']) ? json_decode($taskInfo['result_image_urls'], true) : [];
                
                $resultImages = [];
                $maxCount = max(count($keys), count($urls));
                
                for ($i = 0; $i < $maxCount; $i++) {
                    $image = [];
                    if (isset($keys[$i])) {
                        $image['key'] = $keys[$i];
                    }
                    if (isset($urls[$i])) {
                        $image['url'] = $urls[$i];
                    }
                    if (!empty($image)) {
                        $resultImages[] = $image;
                    }
                }
                
                $responseData['resultImages'] = $resultImages;
            }
            
            // 如果有视频结果，添加结果视频
            if (!empty($taskInfo['result_videos'])) {
                $responseData['resultVideos'] = json_decode($taskInfo['result_videos'], true);
            }
            
            // 如果任务失败，添加错误信息
            if (in_array($taskInfo['status'], [2, 4]) && !empty($taskInfo['error_msg'])) {
                $responseData['errorMsg'] = $taskInfo['error_msg'];
            }

            return json(['code' => 200, 'msg' => 'success', 'data' => $responseData]);
            
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => $e->getMessage(), 'data' => null]);
        }
    }
    
    /**
     * 获取用户任务列表
     */
    public function getUserTasks()
    {
        try {
            $userId = $this->request->user->uid ?? 1; // 临时使用1，实际应从认证中获取
            $page = input('page/d', 1);
            $pageSize = input('pageSize/d', 10);
            $status = input('status', ''); // 可选的状态筛选
            
            $where = ['user_id' => $userId];
            if ($status !== '') {
                $where['status'] = intval($status);
            }
            
            $tasks = Db::name('product_anyshoot_tasks')
                ->where($where)
                ->order('create_time desc')
                ->page($page, $pageSize)
                ->select()->toArray();
                
            $total = Db::name('product_anyshoot_tasks')
                ->where($where)
                ->count();
            
            $statusText = [
                0 => '待处理',
                1 => '图片生成中', 
                2 => '图片生成失败',
                3 => '等待图转视频',
                4 => '图转视频中',
                5 => '图转视频成功',
                6 => '图转视频失败',
                10 => '图片生成中',
            ];
            foreach ($tasks as $key => $task) {
                $tasks[$key]['statusText'] = $statusText[$task['status']] ?? '未知';
                
                // 处理result_images - 只返回第一个key和url到外层
                if (!empty($task['result_image_keys']) || !empty($task['result_image_urls'])) {
                    $keys = !empty($task['result_image_keys']) ? json_decode($task['result_image_keys'], true) : [];
                    $urls = !empty($task['result_image_urls']) ? json_decode($task['result_image_urls'], true) : [];
                    // 只取第一个值，直接放在外层
                    if (!empty($keys) && isset($keys[0])) {
                        $tasks[$key]['key'] = $keys[0];
                    }
                    if (!empty($urls) && isset($urls[0])) {
                        $tasks[$key]['url'] = $urls[0];
                    }
                }
                
                // 清理原始字段，避免返回过多数据
                unset($tasks[$key]['result_image_keys']);
                unset($tasks[$key]['result_image_urls']);
            }
            return json([
                'code' => 200,
                'msg' => 'success',
                'data' => [
                    'list' => $tasks,
                    'total' => $total,
                    'page' => $page,
                    'pageSize' => $pageSize
                ]
            ]);
            
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => $e->getMessage(), 'data' => null]);
        }
    }
    
    /**
     * 开始图转视频任务
     */
    public function startImage2Video()
    {
        try {
            $userId = $this->request->user->uid ?? 1;
            $taskId = input('taskId', '');
            $selectedImageKey = input('selectedImageKey', ''); // 选择的图片key
            $duration = intval(input('duration', 5)); // 默认5秒
            $mode = input('mode', 'lite'); // 默认lite
            $generatingCount = intval(input('generatingCount', 1)); // 默认1
            $prompt = input('prompt', '');
            $negativePrompt = input('negativePrompt', '');
            $noticeUrl = input('noticeUrl', '');

            if (empty($taskId) || empty($selectedImageKey)) {
                return json([
                    'code' => 400,
                    'msg' => '缺少必需参数: taskId 或 selectedImageKey',
                    'data' => null
                ]);
            }

            // 查询任务信息
            $taskInfo = Db::name('product_anyshoot_tasks')
                ->where('id', $taskId)
                ->find();

            if (!$taskInfo) {
                return json([
                    'code' => 404,
                    'msg' => '任务不存在',
                    'data' => null
                ]);
            }

            // 检查任务状态，只有等待图转视频(3)才能开始
            if ($taskInfo['status'] != 3) {
                return json([
                    'code' => 400,
                    'msg' => '任务状态不正确，当前状态: ' . ($taskInfo['status'] == 1 ? '图片生成中' : '其他'),
                    'data' => null
                ]);
            }

            // 1. 计算积分
            $pointsTable = [
                'lite' => [5 => 4.5, 10 => 6],
                'pro'  => [5 => 6, 10 => 9],
                'plus' => [5 => 9, 10 => 16],
                'best' => [5 => 16, 10 => 31],
            ];
            if (!isset($pointsTable[$mode]) || !isset($pointsTable[$mode][$duration])) {
                return json([
                    'code' => 400,
                    'msg' => '不支持的mode或duration',
                    'data' => null
                ]);
            }
            $unitPoints = $pointsTable[$mode][$duration];
            $needPoints = $unitPoints * $generatingCount;
            $pointsService = new PointsService();
            $userPoints = $pointsService->getUserPoints($userId);
            if ($userPoints < $needPoints) {
                return json([
                    'code' => 400,
                    'msg' => "积分不足，需要{$needPoints}积分，当前余额{$userPoints}积分",
                    'data' => null
                ]);
            }

            Db::startTrans();
            try {
                // 2. 扣除积分
                $desc = "万物迁移({$mode} {$duration}s × {$generatingCount})";
                $pointsService->consume($userId, $needPoints, $desc, $taskId);

                // 3. 调用Topview通用image2video接口
                $apiParams = [
                    'imageFileId' => $selectedImageKey,
                    'prompt' => $prompt,
                    'negativePrompt' => $negativePrompt,
                    'duration' => $duration,
                    'mode' => $mode,
                    'generatingCount' => $generatingCount,
                ];
                if ($noticeUrl) {
                    $apiParams['noticeUrl'] = $noticeUrl;
                }

                $result = $this->apiService->submitCommonImage2VideoTask($apiParams);

                // 4. 更新数据库
                Db::name('product_anyshoot_tasks')
                    ->where('id', $taskId)
                    ->update([
                        'video_task_id' => $result['taskId'] ?? '',
                        'status' => 4, // 图转视频中
                        'points_consumed' => Db::raw('points_consumed+' . $needPoints),
                        'update_time' => date('Y-m-d H:i:s')
                    ]);

                Db::commit();

                return json([
                    'code' => 200,
                    'msg' => '图转视频任务已开始',
                    'data' => [
                        'taskId' => $taskId,
                        'videoTaskId' => $result['taskId'] ?? '',
                        'status' => 4,
                        'statusText' => '图转视频中',
                        'consumed_points' => $needPoints,
                        'remaining_points' => $userPoints - $needPoints,
                        'message' => $result['message'] ?? '图转视频任务已提交'
                    ]
                ]);
            } catch (\Exception $e) {
                Db::rollback();
                return json(['code' => 500, 'msg' => $e->getMessage(), 'data' => null]);
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => $e->getMessage(), 'data' => null]);
        }
    }

    /**
     * 提交 Product AnyShoot v2 背景任务
     * 文档: https://s.apifox.cn/e8e2bcff-c3c8-4f04-9b5c-465e985c31bc/api-338339541
     */
    public function submitProductBackgroundTask()
    {
        try {
            $userId = $this->request->user->uid ?? 1;
            $params = input('post.');

            // 基础校验：至少需要一个图片文件ID
            $imageFileId = $params['productImageFileId'] ?? ($params['imageFileId'] ?? '');
            if (empty($imageFileId)) {
                return json([
                    'code' => 400,
                    'msg' => '缺少必需参数: productImageFileId 或 imageFileId',
                    'data' => null
                ]);
            }

            // 计费：按生成数量计费，默认1张，每张1积分（可根据业务调整）
            $generatingCount = intval($params['generatingCount'] ?? 1);
            if ($generatingCount <= 0) { $generatingCount = 1; }
            $unitPoints = 1.0;
            $needPoints = $unitPoints * $generatingCount;

            $pointsService = new PointsService();
            $userPoints = $pointsService->getUserPoints($userId);
            if ($userPoints < $needPoints) {
                return json([
                    'code' => 400,
                    'msg' => "积分不足，需要{$needPoints}积分，当前余额{$userPoints}积分",
                    'data' => null
                ]);
            }

            // 事务：扣积分 + 调用API + 入库
            \think\facade\Db::startTrans();
            try {
                $pointsService->consume($userId, $needPoints, '背景替换任务('.$generatingCount.'张)');

                $result = $this->apiService->submitProductBackgroundTask($params);
                $remoteTaskId = $result['taskId'] ?? ($result['result']['taskId'] ?? '');
                if (empty($remoteTaskId)) {
                    throw new \Exception('API调用成功但未返回taskId');
                }

                // 入库到 product_anyshoot_tasks（以 template_id = background_v2 做区分）
                $taskDbId = \think\facade\Db::name('product_anyshoot_tasks')->insertGetId([
                    'user_id' => $userId,
                    'task_id' => $remoteTaskId,
                    'template_id' => 'background_v2',
                    'product_image_file_id' => $imageFileId,
                    'product_mask_file_id' => $params['productMaskFileId'] ?? null,
                    'template_image_file_id' => $params['templateImageFileId'] ?? null,
                    'template_mask_file_id' => $params['templateMaskFileId'] ?? null,
                    'mode' => $params['mode'] ?? 'advanced',
                    'generating_count' => $generatingCount,
                    'status' => 10, // 图片生成中
                    'points_consumed' => $needPoints,
                    'create_time' => date('Y-m-d H:i:s')
                ]);

                \think\facade\Db::commit();

                return json([
                    'code' => 200,
                    'msg' => '任务提交成功',
                    'data' => [
                        'taskId' => $remoteTaskId,
                        'dbTaskId' => $taskDbId,
                        'status' => 1,
                        'statusText' => '图片生成中',
                        'consumed_points' => $needPoints,
                        'remaining_points' => $userPoints - $needPoints
                    ]
                ]);
            } catch (\Exception $e) {
                \think\facade\Db::rollback();
                throw $e;
            }
        } catch (\Exception $e) {
            return json(['code' => 500, 'msg' => $e->getMessage(), 'data' => null]);
        }
    }
} 